package Client.View;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;

import Client.Model.GameModel;
import Ships.Ship;

import logic.Board;

@SuppressWarnings("serial")
class GamePlayCanvas extends JPanel implements MouseListener, MouseMotionListener{
	
	/**
	 * 
	 */
	
	private final static int BOARD_SQUARE_SIZE = 30;
	
	private final static int BOARD_BASE_X = 20;
	private final static int BOARD_BASE_Y = 10;
	
	
	Board board;
	GameModel model;
	int width;
	int height;
	
	Image shotMissed, shotOnTarget;
	
	boolean enemyView;
	
	int currentX=0;
	int currentY=0;
	
	public GamePlayCanvas(GameModel model, int width, int height, boolean enemyView) {
	
		this.model = model;
		this.height = height;
		this.width = width;
		this.enemyView = enemyView;
		
		if (!enemyView)
			this.board = model.getBoard();
		else
			this.board = model.getEnemyBoard();
		
		setMinimumSize(new Dimension(width, height));
		setPreferredSize(new Dimension(width, height));
		
		this.addMouseListener(this);
		this.addMouseMotionListener(this);
		
		setOpaque(false);
				
	}
	

	@Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);

		
		if (!enemyView)
			this.board = model.getBoard();
		else
			this.board = model.getEnemyBoard();
		
		if (board==null)
			return;
		
		paintBoard(g);
		
		paintShips(g);
				
		if (enemyView)
			paintSelected(g);
				
		paintShots(g);
		
	}
	
	
	private void paintShips(Graphics g) {
				
		if (enemyView){
			for (Ship ship: board.getShips())
				drawShip(g, ship, getX(ship.getCol_ini()), getY(ship.getLin_ini()), Color.BLUE);
		}
		else{
			for (Ship ship: board.getShips())
				drawShip(g, ship, getX(ship.getCol_ini()), getY(ship.getLin_ini()), Color.BLUE);
		}
			
		
	}

	
	private void drawShip(Graphics g, Ship ship, int x, int y, Color c){
		
		g.setColor(c);
		
		if (ship.getOrientation()==Ship.HORIZONTAL){
			
			g.fillRect(x+1, y+1, BOARD_SQUARE_SIZE * ship.getSize() - 2, BOARD_SQUARE_SIZE - 2);
			
			g.setColor(Color.BLACK);
			g.drawRect(x+1, y+1, BOARD_SQUARE_SIZE * ship.getSize() - 2, BOARD_SQUARE_SIZE - 2);
		}
		else{
			g.fillRect(x+1, y+1, BOARD_SQUARE_SIZE -2, BOARD_SQUARE_SIZE * ship.getSize() -2);
			
			g.setColor(Color.BLACK);
			g.drawRect(x+1, y+1, BOARD_SQUARE_SIZE -2, BOARD_SQUARE_SIZE * ship.getSize() -2);
		}
		
	}

	private void paintShots(Graphics g) {
		
		loadImages();
		
		for (int l=0; l<board.getNLines(); l++)
			for (int c=0; c<board.getNColumns(); c++)
				if (board.getStateAt(l,c) == Board.BOARD_SHOT_IN_SHIP)
					g.drawImage(shotOnTarget, getX(c), getY(l), null);
				else
					if (board.getStateAt(l,c) == Board.BOARD_SHOT_IN_WATER)
						g.drawImage(shotMissed, getX(c), getY(l), null);

		
	}
	
	private void paintSelected(Graphics g){

		int line = getLine(currentY);
		int col = getColumn(currentX);

		if (line>=0 && line<board.getNLines() && col>=0 && col<board.getNColumns()){
			if (board.getStateAt(line, col)==Board.BOARD_EMPTY)
				g.setColor(new Color(0,204,0, 100)); //green
			else
				g.setColor(new Color(249,86,6, 200));

			g.fillRect(getX(col), getY(line), BOARD_SQUARE_SIZE, BOARD_SQUARE_SIZE);
		}

	}
	

	private void loadImages(){
		
		BufferedImage img = null;
		
		try {
		    img = ImageIO.read(new File("./bin/Client/View/images/fire.png"));
		    shotOnTarget = img;
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		try {
		    img = ImageIO.read(new File("./bin/Client/View/images/waterdrop.png"));
		    shotMissed = img;
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void paintBoard(Graphics g) {
		
		//draw border
		g.setColor(Color.BLACK);
		g.drawRect(BOARD_BASE_X, BOARD_BASE_Y, BOARD_SQUARE_SIZE * board.getNColumns(), BOARD_SQUARE_SIZE * board.getNLines());
		
		//draw background
		g.setColor(Color.CYAN);
		g.fillRect(BOARD_BASE_X, BOARD_BASE_Y, BOARD_SQUARE_SIZE * board.getNColumns(), BOARD_SQUARE_SIZE * board.getNLines());
		
		
		g.setColor(Color.GRAY);
		
		//draw vertical lines
		for (int i=0; i<board.getNColumns(); i++)
			g.drawLine(getX(i), BOARD_BASE_Y, getX(i), getY(board.getNLines()));
		
		//draw horizontal lines
		for (int i=0; i<board.getNLines(); i++)
			g.drawLine(BOARD_BASE_X, getY(i), getX(board.getNColumns()), getY(i));
			
		
		
	}

	int getX(int column){
		
		return BOARD_BASE_X + (column*BOARD_SQUARE_SIZE);
		
	}
	
	int getY(int line){
		
		return BOARD_BASE_Y + (line*BOARD_SQUARE_SIZE);
	}
	
	int getLine(int Y){

		Y -= BOARD_BASE_Y;
		return Y/BOARD_SQUARE_SIZE;

	}
	
	int getColumn(int X){
		
		X -= BOARD_BASE_X;
		return X/BOARD_SQUARE_SIZE;
	}

	
	//--------- Mouse Listeners ----------
			

	@Override
	public void mouseClicked(MouseEvent e) {
		
	}

	@Override
	public void mouseEntered(MouseEvent e) {
		
		if (enemyView)
			setCursor (Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
	}

	@Override
	public void mouseExited(MouseEvent e) {
		setCursor (Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
	}

	@Override
	public void mousePressed(MouseEvent e) {
		
		if (enemyView){
			
			int x = e.getX();
			int y = e.getY();

			if (model.getGamestate()==GameModel.STATE_PLAYING && model.isMyTurn())
				model.shotAt(getLine(y), getColumn(x));
			
		}
	}

	@Override
	public void mouseReleased(MouseEvent e) {
	}


	@Override
	public void mouseDragged(MouseEvent e) {
							
	}


	@Override
	public void mouseMoved(MouseEvent e) {
		
		currentX = e.getX();
		currentY = e.getY();
		
		repaint();
		
	}

	

	
}